#!/usr/bin/env python2
PACKAGE = "davis_ros_driver"

from dynamic_reconfigure.parameter_generator_catkin import *

gen = ParameterGenerator()

gen.add("streaming_rate", int_t, 0, "integration time (0 is instant sending)", 30, 0, 10000)
gen.add("max_events", int_t, 0, "max. events per packet (0 is no limit)", 0, 0, 100000)

gen.add("aps_enabled", bool_t, 0, "enables APS", True)
gen.add("dvs_enabled", bool_t, 0, "enables DVS", True)
gen.add("imu_enabled", bool_t, 0, "enables IMU", True)

gen.add("autoexposure_enabled", bool_t, 0, "enables the RPG auto-exposure algorithm (experimental)", False)
gen.add("autoexposure_gain", int_t, 0, "auto-exposure gain (lower: slow response time, without oscillations / higher: faster response time, with oscillations", 3, 1, 10)
gen.add("autoexposure_desired_intensity", int_t, 0, "desired mean image intensity: controls the overall image brightness", 75, 0, 255)
gen.add("exposure", int_t, 0, "exposure (frame exposure time in microseconds)", 5000, 0, 1000000)
frame_mode_enum = gen.enum([	gen.const("Default", 		int_t, 0, "Grayscale for mono cameras and RGB for color cameras"),
                              gen.const("Grayscale", 	int_t, 1, "Always a grayscale intensity frame"),
                              gen.const("Original", 	int_t, 2, "Exactly as it comes from the device (will show grid pattern on color cameras)")],
                              "Desired type of frame output")
gen.add("frame_mode", int_t, 0, "Desired type of frame output", 0, 0, 2, edit_method=frame_mode_enum)
gen.add("frame_interval", int_t, 0, "frame interval (best-effort time between consecutive frames in microseconds)", 25000, 0, 8388607)

# Hardware Filters
grp_hardware_filters = gen.add_group("Hardware_Filters")
grp_hardware_filters.add("background_activity_filter_enabled", bool_t, 1, "enables background activity filter", True)
grp_hardware_filters.add("background_activity_filter_time", int_t, 1, "background activity filter time (in blocks of 250 microseconds).", 80, 0, 400)
grp_hardware_filters.add("refractory_period_enabled", bool_t, 1, "enables refractory period filter", False)
grp_hardware_filters.add("refractory_period_time", int_t, 1, "refractory period time (in blocks of 250 microseconds)", 2, 0, 20)
grp_hardware_filters.add("skip_enabled", bool_t, 1, "enables the event skip filter, which throws away one event every N events (decimation filter)", False)
grp_hardware_filters.add("skip_every", int_t, 1, "number of events to let through before skipping one", 0, 0, 255)
grp_hardware_filters.add("polarity_suppress", bool_t, 1, "suppress one of the two ON/OFF polarities completely", False)
grp_hardware_filters.add("polarity_suppress_type", bool_t, 1, "polarity to suppress (0=OFF, 1=ON)", False)
grp_hardware_filters.add("polarity_flatten", bool_t, 1, "flatten all polarities to OFF; applied after supression", False)
dvs_roi = grp_hardware_filters.add_group("DVS region of interest")
dvs_roi.add("roi_start_column", int_t, 1, "start position on the X axis for DVS region of interest", 0, 0, 345)
dvs_roi.add("roi_start_row", int_t, 1, "start position on the Y axis for DVS region of interest", 0, 0, 259)
dvs_roi.add("roi_end_column", int_t, 1, "end position on the X axis for DVS region of interest", 345, 0, 345)
dvs_roi.add("roi_end_row", int_t, 1, "end position on the Y axis for DVS region of interest", 259, 0, 259)
aps_roi = grp_hardware_filters.add_group("APS region of interest")
aps_roi.add("aps_roi_start_column", int_t, 1, "start position on the X axis for APS region of interest", 0, 0, 345)
aps_roi.add("aps_roi_start_row", int_t, 1, "start position on the Y axis for APS region of interest", 0, 0, 259)
aps_roi.add("aps_roi_end_column", int_t, 1, "end position on the X axis for APS region of interest", 345, 0, 345)
aps_roi.add("aps_roi_end_row", int_t, 1, "end position on the Y axis for APS region of interest", 259, 0, 259)
pixel_filter = grp_hardware_filters.add_group("Pixel Filter")
pixel_filter.add("pixel_0_row", int_t, 1, "pixel 0, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_0_column", int_t, 1, "pixel 0, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_1_row", int_t, 1, "pixel 1, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_1_column", int_t, 1, "pixel 1, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_2_row", int_t, 1, "pixel 2, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_2_column", int_t, 1, "pixel 2, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_3_row", int_t, 1, "pixel 3, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_3_column", int_t, 1, "pixel 3, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_4_row", int_t, 1, "pixel 4, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_4_column", int_t, 1, "pixel 4, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_5_row", int_t, 1, "pixel 5, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_5_column", int_t, 1, "pixel 5, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_6_row", int_t, 1, "pixel 6, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_6_column", int_t, 1, "pixel 6, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_7_row", int_t, 1, "pixel 3, Y axis setting", 259, 0, 259)
pixel_filter.add("pixel_7_column", int_t, 1, "pixel 7, X axis setting", 345, 0, 345)
pixel_filter.add("pixel_auto_train", bool_t, 1, "enable automatic filtering of 8 most active pixels (above ~5KHz)", False)

# DAVIS Biasing
# a bias consists of a coarse 3 bit value and a fine 8 bit value.
# Coarse values are logarithmic and adding one means ~8 times higher current
# fine values are linear and produce the output current range [0, coarse]. This
# means setting a fine value to 32 is equal to decreasing coarse by 1 and
# setting fine to 255.

# if you want only one event per illumination change, use: high PrBp, PrSFBn and
# low DiffBn

def addBias(grp, name, descr, coarse_def, fine_def):
	grp.add(name+"_coarse", int_t, 1, descr+" (coarse, logarithmic)", coarse_def, 0, 7)
	grp.add(name+"_fine", int_t, 1, descr+" (fine, linear)", fine_def, 0, 255)

# On-chip voltage digital-to-analog converter configuration
# The voltage is expressed as a fraction of 1/64th of VDD=3.3V
def addVdacBias(grp, name, descr, volt_def, curr_def):
    grp.add(name+"_volt", int_t, 1, descr+" (voltage)", volt_def, 0, 63)
    grp.add(name+"_curr", int_t, 1, descr+" (current)", curr_def, 0, 7)

grp_stage_one = gen.add_group("DAVIS_Biases_Stage_1")
addBias(grp_stage_one, "PrBp",
	"Amplifier in first stage. Limits the speed. Higher=faster and more noise", 2, 58)
addBias(grp_stage_one, "PrSFBp",
	"Source follower: set high to allow higher pixel bandwidth (has no influence if set high enough)", 1, 33)

grp_stage_two = gen.add_group("DAVIS_Biases_Stage_2")
addBias(grp_stage_two, "DiffBn",
	"Amplifier of second stage. Indep of actual illumination level. rebalance ONBn/OFFBn after changing this", 4, 39)
addBias(grp_stage_two, "ONBn",
	"Threshold for ON events (contrast sensitivity). Must be >DiffBn.", 6, 200)
addBias(grp_stage_two, "OFFBn",
	"Threshold for OFF events (contrast sensitivity). Must be <DiffBn.", 4, 0)
addBias(grp_stage_two, "RefrBp",
	"Maximum pixel firing rate (reset time before it can start to detect changes again)", 4, 25)

grp_aps = gen.add_group("DAVIS_Biases_APS")
addVdacBias(grp_aps, "ADC_RefHigh", "APS ADC upper conversion limit", 27, 7)
addVdacBias(grp_aps, "ADC_RefLow", "APS ADC lower conversion limit", 1, 7)

imu_acc_scale_enum = gen.enum([ gen.const("2g",         int_t, 0, "+/- 2 g"),
                                gen.const("4g",         int_t, 1, "+/- 4 g"),
                                gen.const("8g",         int_t, 2, "+/- 8 g"),
                                gen.const("16g",        int_t, 3, "+/- 16 g")],
                                "Full scale of the accelerometer")

imu_gyro_scale_enum = gen.enum([ gen.const("250degps",  int_t, 0, "+/- 250 deg/s"),
                                 gen.const("500degps",  int_t, 1, "+/- 500 deg/s"),
                                 gen.const("1000degps", int_t, 2, "+/- 1000 deg/s"),
                                 gen.const("2000degps", int_t, 3, "+/- 2000 deg/s")],
                                 "Full scale of the gyroscope")

imu_low_pass_filter_enum = gen.enum([ gen.const("260hz",  int_t, 0, "260/256 Hz - delay: 0.0/0.98 ms"),
                                 gen.const("184hz",  int_t, 1, "184/188 Hz - delay: 2.0/1.9 ms"),
                                 gen.const("94hz",  int_t, 2, "94/98 Hz - delay: 3.0/2.8 ms"),
                                 gen.const("44hz", int_t, 3, "44/42 Hz - delay: 4.9/4.8 ms"),
                                 gen.const("21hz", int_t, 4, "21/20 Hz - delay: 8.5/8.3 ms"),
                                 gen.const("10hz", int_t, 5, "10/10 Hz - delay: 13.8/13.4 ms"),
                                 gen.const("5hz", int_t, 6, "5/5 Hz - delay: 19.0/18.6 ms")],
                                 "Bandwidth of the low pass filter applied to the accelerometer/gyroscope")

gen.add("imu_acc_scale", int_t, 0, "Full scale of the accelerometer", 3, 0, 3, edit_method=imu_acc_scale_enum)
gen.add("imu_gyro_scale", int_t, 0, "Full scale of the gyroscope", 3, 0, 3, edit_method=imu_gyro_scale_enum)
gen.add("imu_low_pass_filter", int_t, 0, "Bandwidth of the low-pass filter applied to the accelerometer/gyroscope", 1, 0, 6, edit_method=imu_low_pass_filter_enum)

exit(gen.generate(PACKAGE, "davis_ros_driver", "DAVIS_ROS_Driver"))
